//! 日期时间生成器模块

use chrono::{DateTime, Duration, NaiveDate, Utc, Datelike};
use rand::Rng;
use rand::seq::SliceRandom;

/// 生成指定范围内的随机日期时间
pub fn datetime_range(start: DateTime<Utc>, end: DateTime<Utc>) -> DateTime<Utc> {
    let mut rng = rand::thread_rng();
    let secs = end.timestamp() - start.timestamp();
    let random_secs = rng.gen_range(0..secs);
    start + Duration::seconds(random_secs)
}

/// 生成过去N天内的随机日期时间
pub fn datetime_past_days(days: i64) -> DateTime<Utc> {
    let now = Utc::now();
    let past = now - Duration::days(days);
    datetime_range(past, now)
}

/// 生成未来N天内的随机日期时间
pub fn datetime_future_days(days: i64) -> DateTime<Utc> {
    let now = Utc::now();
    let future = now + Duration::days(days);
    datetime_range(now, future)
}

/// 生成今年内的随机日期
pub fn datetime_this_year() -> DateTime<Utc> {
    let now = Utc::now();
    let year = now.year();
    let start = NaiveDate::from_ymd_opt(year, 1, 1)
        .unwrap()
        .and_hms_opt(0, 0, 0)
        .unwrap()
        .and_utc();
    let end = NaiveDate::from_ymd_opt(year, 12, 31)
        .unwrap()
        .and_hms_opt(23, 59, 59)
        .unwrap()
        .and_utc();
    datetime_range(start, end)
}

/// 生成生日日期（18-80岁之间）
pub fn birthday() -> String {
    let now = Utc::now();
    let min_age = 18;
    let max_age = 80;
    
    let mut rng = rand::thread_rng();
    let age = rng.gen_range(min_age..=max_age);
    
    let birth_year = now.year() - age;
    let birth_month = rng.gen_range(1..=12);
    let birth_day = rng.gen_range(1..=28); // 简化处理，避免月份天数问题
    
    NaiveDate::from_ymd_opt(birth_year, birth_month, birth_day)
        .unwrap()
        .format("%Y-%m-%d")
        .to_string()
}

/// 生成工作时间（9:00-18:00）
pub fn work_time() -> String {
    let mut rng = rand::thread_rng();
    let hour = rng.gen_range(9..18);
    let minute = rng.gen_range(0..60);
    format!("{:02}:{:02}", hour, minute)
}

/// 生成时间戳
pub fn timestamp() -> i64 {
    Utc::now().timestamp()
}

/// 生成RFC2822格式的日期时间字符串
pub fn rfc2822() -> String {
    Utc::now().to_rfc2822()
}

/// 生成指定范围内的日期
pub fn date_between(start: &str, end: &str) -> String {
    let mut rng = rand::thread_rng();
    let start_date = NaiveDate::parse_from_str(start, "%Y-%m-%d").unwrap();
    let end_date = NaiveDate::parse_from_str(end, "%Y-%m-%d").unwrap();
    let days_diff = end_date.signed_duration_since(start_date).num_days();
    let random_days = rng.gen_range(0..=days_diff);
    let result_date = start_date + chrono::Duration::days(random_days);
    result_date.format("%Y-%m-%d").to_string()
}

/// 生成时间字符串（HH:MM:SS）
pub fn time() -> String {
    let mut rng = rand::thread_rng();
    let hour = rng.gen_range(0..24);
    let minute = rng.gen_range(0..60);
    let second = rng.gen_range(0..60);
    format!("{:02}:{:02}:{:02}", hour, minute, second)
}

/// 生成日期时间字符串（YYYY-MM-DD HH:MM:SS）
pub fn datetime() -> String {
    let date = birthday();
    let time_str = time();
    format!("{} {}", date, time_str)
}

/// 生成星期几
pub fn weekday() -> String {
    let mut rng = rand::thread_rng();
    let weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
    weekdays.choose(&mut rng).unwrap().to_string()
}

/// 生成月份
pub fn month() -> String {
    let mut rng = rand::thread_rng();
    let months = ["January", "February", "March", "April", "May", "June",
                  "July", "August", "September", "October", "November", "December"];
    months.choose(&mut rng).unwrap().to_string()
}

/// 生成ISO 8601格式的日期时间字符串
pub fn iso8601() -> String {
    Utc::now().to_rfc3339()
}

/// 生成指定范围内的随机日期
pub fn random_date_between(start: &str, end: &str) -> String {
    date_between(start, end)
}

/// 生成日期（ISO格式）
pub fn date_iso() -> String {
    Utc::now().format("%Y-%m-%d").to_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_datetime_past_days() {
        let dt = datetime_past_days(30);
        let now = Utc::now();
        assert!(dt < now);
        assert!(dt > now - Duration::days(30));
    }

    #[test]
    fn test_birthday() {
        let birth_str = birthday();
        let birth_date = NaiveDate::parse_from_str(&birth_str, "%Y-%m-%d").unwrap();
        let now = Utc::now();
        let age = now.year() - birth_date.year();
        assert!(age >= 18 && age <= 80);
    }

    #[test]
    fn test_work_time() {
        let time = work_time();
        assert!(time.contains(':'));
        let parts: Vec<&str> = time.split(':').collect();
        assert_eq!(parts.len(), 2);
        
        let hour: u32 = parts[0].parse().unwrap();
        assert!(hour >= 9 && hour < 18);
    }
}